<?php
/**
 * Created by 784855684@qq.com.
 * Link: https://github.com/lichtung/inframe
 * User: linzh
 * Date: 6/25/17
 * Time: 6:01 PM
 */


namespace inframe\core;

use inframe\throws\DatabaseException;
use inframe\throws\db\RecordNotFoundException;

/**
 * Class ActiveRecord
 * @package inframe\core
 */
abstract class ActiveRecord extends Model
{
    /**
     * @var int 主键值
     */
    public $id = null;
    /**
     * @var array id对应的数据
     */
    protected $data = [];


    public function clear()
    {
        $this->id = null;
        $this->data = [];
        return $this;
    }

    /**
     * ActiveRecord constructor.
     * @param int|null $id 表的主键
     * @throws RecordNotFoundException
     */
    public function __construct($id = null)
    {
        parent::__construct();
        if ($id) {
            if (!($data = $this->find($id))) throw new RecordNotFoundException("ID '{$id}' not found ");
            $this->data = $data;
            $this->id = $this->data[$this->pk];
        }
    }

    public function data()
    {
        return $this->data;
    }

    public function __get($name)
    {
        return isset($this->data[$name]) ? $this->data[$name] : null;
    }

    public function __set($name, $value)
    {
        $this->data[$name] = $value;
    }

    /**
     * 保存数据
     * 当主键id被指定了之后（构造时指定了参数ID），save操作将会执行数据的修改操作；否则将添加数据
     * 如果需要验证信息，可以在调用parent::save()之前验证数据是否合法
     * @param bool $justInsert 是否是插入操作，为true时只进行插入操作
     * @return bool 返回是否成功
     * @throws DatabaseException
     */
    public function save($justInsert = false)
    {
        try {
            if (!$justInsert and $this->id) {
                unset($this->data[$this->pk]);
                $this->update($this->data, [$this->pk => $this->id]);
            } else {
                $this->{$this->pk} = null;
                unset($this->data[$this->pk]);
                $this->insert($this->data);
                $this->id = $this->lastInsertId();
            }
            $this->reload();
            return true;
        } catch (\Throwable $e) {
            throw new DatabaseException($e->getMessage());
        }
    }

    /**
     * 获取全部数据
     * @param bool $reload 是否刷新
     * @return array
     */
    public function all($reload = false)
    {
        $reload and $this->reload();
        return $this->data;
    }

    /**
     * 刷新数据
     * @return $this
     * @throws RecordNotFoundException id未指定时刷新将抛出异常
     */
    public function reload()
    {
        if ($this->id) {
            $this->data = $this->find($this->id);
        } else {
            throw new RecordNotFoundException('id not specialized');
        }
        return $this;
    }

    public function remove()
    {
        if (isset($this->id)) {
            $this->reload();
            Logger::getLogger('database')->info([$this->data, $this->id]);
            return $this->delete([$this->pk => $this->id]) > 0;
        } else {
            return false;
        }
    }


    public function __toString()
    {
        return json_encode($this->data);
    }
}